#include <linux/list.h>
#include <linux/slab.h>
#include <linux/printk.h>
#include <linux/string.h> 

typedef struct tagMyData MyData;

struct tagMyData
{
    char name[10];
    int index;
    struct list_head list;
};

static MyData *pData;

MyData *create_data(int idx, char *name)
{
    MyData *retData;
    retData = kmalloc(sizeof(MyData), GFP_KERNEL);
    if (!retData) {
        return NULL;
    }
    INIT_LIST_HEAD(&retData->list);
    retData->index = idx;
    strcpy(retData->name, name);
    return retData;
}

void create_all(void)
{
    int i;
    MyData *tmp;
    char name[10] = "data ";
    for (i=1; i<10; i++) {
        name[4] = (char)(i+47);
        printk(KERN_INFO "EX3: create %d, %s", i, name);
        tmp = create_data(i, name);
        list_add_tail(&tmp->list, &pData->list);
    }
}

void prink_all(void)
{
    MyData *tmp;
    struct list_head *pos;
    struct list_head *head;
    int cnt;

    cnt = 0;
    head = &pData->list;
    printk(KERN_INFO "EX3: %d, %d, %s", 0, pData->index, pData->name);
    list_for_each(pos, head) {
        cnt++;
        tmp = list_entry(pos, MyData, list);
        printk(KERN_INFO "EX3: %d, %d, %s", cnt, tmp->index, tmp->name);
    }
}

void free_all(void)
{
    MyData *pos, *next;
    list_for_each_entry_safe(pos, next, &pData->list, list) {
        list_del(&pos->list);
        kfree(pos);
    }
}

int task_init(void)
{
    pData = create_data(0, "head");
    create_all();
    prink_all();
    free_all();
    return 0;
}

int task_exit(void)
{
    return 0;
}